/**
 * 
 */
package com.ws.framework.remoteservice.core;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.AbstractApplicationContext;

import com.ws.framework.remoteservice.core.ex.AnnotationNotFoundException;
import com.ws.framework.remoteservice.core.ex.WRSIException;
import com.ws.framework.remoteservice.core.provider.ServicePublisher;



/**
 * @author WSH
 *
 */
public class ServiceBean implements ApplicationListener<ContextRefreshedEvent>, DisposableBean {
	
	private final Logger logger = Logger.getLogger(this.getClass().getName());

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		 Map<String, Object> allBeans = getAllBeans(event.getApplicationContext());
	        for (Map.Entry<String, Object> entry : allBeans.entrySet()) {
	            String beanName = entry.getKey();
	            Object bean = entry.getValue();
	            try {
	                Class<?> targetClass = AopUtils.getTargetClass(bean);
	                if (targetClass == null) {
	                    logger.warning("Can not get targetClass of bean " + beanName);
	                    continue;
	                }
	                ServicePublisher.publish(bean, targetClass);
	            } catch (AnnotationNotFoundException ex) {
	                //Ignore
	            } catch (WRSIException ex) {
	                logger.warning("can not publish service " + beanName);
	                throw ex;
	            } catch (Exception e) {
	                logger.warning("can not publish service " + beanName);
	                throw new WRSIException(e);
	            }
	        }
	        logger.info("End export remote services.");
	}
	
    private static Map<String, Object> getAllBeans(ApplicationContext ctx) {
        Map<String, Object> beans = new HashMap<String, Object>();
        String[] all = ctx.getBeanDefinitionNames();
        BeanFactory factory = ((AbstractApplicationContext) ctx).getBeanFactory();
        for (String name : all) {
            try {
                Object s = factory.getBean(name);
                if (s != null)
                    beans.put(name, s);
            } catch (BeansException e) {
                //ignore
            }
        }
        return beans;
    }

	@Override
	public void destroy() throws Exception {
		ServicePublisher.destroy();
	}


}
